#if 0
#include <buola/gui.h>

#include <buola/image/cgc.h>
#include <buola/gui/cpropertyeditor.h>
#include <buola/gui/cicon.h>
#include <buola/gui/cconfig.h>
#include <buola/gui/cpropertyfield.h>

#include <buola/widgets/cscrollbar.h>
#include <buola/widgets/ctablebox.h>
#include <buola/widgets/crulerbox.h>
#include <buola/widgets/ctheme.h>

namespace buola { namespace gui {

CTableBox::CTableBox()
{
    SetFocusMode(FOCUS_MOUSE|FOCUS_TAB);
    mScrollPos={0,0};
    mField=nullptr;

    mSelected.mValid=false;
    mEditing.mValid=false;

    mIconStyle=CIcon::MEDIUM;
}

CTableBox::~CTableBox()
{
}

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
////////////////////////// Interface //////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

void CTableBox::Clear()
{
    EndEditing();
    mValues.clear();

    FillRuler();
    UpdateScrollBars();
}

void CTableBox::SetSize(int pRows,int pCols)
{
    EndEditing();
    mValues.resize(pRows,pCols);

    FillRuler();
    UpdateScrollBars();

}

void CTableBox::SetField(CPropertyField *pField)
{
    mField=pField;
}

void CTableBox::SetRowTitle(int i,const std::wstring &pName)
{
    mVRuler->SetFieldName(i,pName);
    mVRuler->Refresh();
}

void CTableBox::SetColTitle(int i,const std::wstring &pName)
{
    mHRuler->SetFieldName(i,pName);
    mHRuler->Refresh();
}

void CTableBox::SetValues(const matrix<UAny> &pValues)
{
    mValues=pValues;
}

void CTableBox::SetValue(TID pRow,TID pCol,const UAny &pValue)
{
    mValues(pRow,pCol)=pValue;
}

const UAny &CTableBox::GetValue(TID pRow,TID pCol)
{
    return mValues(pRow,pCol);
}

void CTableBox::EditCell(TID pRow,TID pCol)
{
    StartEditing(pRow,pCol);
}

void CTableBox::EnsureVisible(TID pRow,TID pCol,bool pMore)
{
    CRect_d lRect(CPoint_d(mHRuler->GetField(pCol).mPos,
                    mVRuler->GetField(pRow).mPos)-mScrollPos,
                CSize_d(mHRuler->GetField(pCol).mSize,
                    mVRuler->GetField(pRow).mSize));
        
    CPoint_d lScrollBy(0,0);
    
    CSize_d lMargin(mRect.w()-lRect.w(),mRect.h()-lRect.h());
    
    if(lMargin.x<0||!pMore) lMargin.x=0;
    if(lMargin.y<0||!pMore) lMargin.y=0;
                            
    if(lRect.l<mRect.l)
    {
        lScrollBy.x-=(mRect.l-lRect.l)+lMargin.x*2/3;
    }
    else if(lRect.r>mRect.r)
    {
        lScrollBy.x+=(lRect.r-mRect.r)+lMargin.x*2/3;
    }
    if(lRect.t<mRect.t)
    {
        lScrollBy.y-=(mRect.t-lRect.t)+lMargin.y*2/3;
    }
    else if(lRect.b>mRect.b)
    {
        lScrollBy.y+=(lRect.b-mRect.b)+lMargin.y*2/3;
    }
    
    if(lScrollBy.x==0&&lScrollBy.y==0) return;
    
    CPoint_d lNewPos=mScrollPos+lScrollBy;
    if(lNewPos.x<0) lNewPos.x=0;
    if(lNewPos.x>mXRange) lNewPos.x=mXRange;
    if(lNewPos.y<0) lNewPos.y=0;
    if(lNewPos.y>mYRange) lNewPos.y=mYRange;

    if(lNewPos==mScrollPos) return;
    
    mHScroll->SetValue((int)lNewPos.x);
    mVScroll->SetValue((int)lNewPos.y);
}

void CTableBox::SetIconStyle(int pStyle)
{
    if(pStyle!=mIconStyle)
    {
        mIconStyle=pStyle;
        Refresh();
    }
}

void CTableBox::HighlightRow(int pRow,const img::CColor &pColor)
{
    mVRuler->HighlightNone();
    mVRuler->HighlightField(pRow,pColor);
}

void CTableBox::HighlightCol(int pCol,const img::CColor &pColor)
{
    mHRuler->HighlightNone();
    mHRuler->HighlightField(pCol,pColor);
}

void CTableBox::HighlightNone()
{
    mHRuler->HighlightNone();
    mVRuler->HighlightNone();
}

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////// Internal functions //////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

void CTableBox::UpdateScrollBars()
{
    const CRulerBox::SField *lHLast=nullptr;
    const CRulerBox::SField *lVLast=nullptr;
    mXRange=0;
    mYRange=0;
    
    if(mValues.size1()) //number of rows
    {
        lVLast=&mVRuler->GetField(mValues.size1()-1);
        mYRange=lVLast->mPos+lVLast->mSize-mRect.h();
    }
    if(mValues.size2()) //number of columns
    {
        lHLast=&mHRuler->GetField(mValues.size2()-1);
        mXRange=lHLast->mPos+lHLast->mSize-mRect.w();
    }
    
    if(mXRange<=0)
    {
        mHScroll->SetRange(0,0);
    }
    else
    {
        mHScroll->SetRange(0,(int)mXRange);
        mHScroll->SetStep((int)lHLast->mSize,(int)mRect.w());
    }

    if(mYRange<=0)
    {
        mVScroll->SetRange(0,0);
    }
    else
    {
        mVScroll->SetRange(0,(int)mYRange);
        mVScroll->SetStep((int)lVLast->mSize,(int)mRect.h());
    }
}

void CTableBox::FillRuler()
{
    mHRuler->RemoveFields();
    mVRuler->RemoveFields();
    
    for(int i=0;i<mValues.size1();i++)
    {
        mVRuler->AddField(i,L"",nullptr,20);
    }
    for(int i=0;i<mValues.size2();i++)
    {
        mHRuler->AddField(i,L"",nullptr,70);
    }

    mHRuler->Refresh();
    mVRuler->Refresh();
}

void CTableBox::DrawAll(img::CGC *pGC)
{
    DrawAll(pGC,mRect);
}

void CTableBox::DrawAll(img::CGC *pGC,const CRect_d &pRect)
{
    for(int i=0;i<mValues.size1();i++)
    {
        for(int j=0;j<mValues.size2();j++)
        {
            CPoint_d lPos(mHRuler->GetField(j).mPos,
                            mVRuler->GetField(i).mPos);
            lPos-=mScrollPos;
            CSize_d lSize(mHRuler->GetField(j).mSize,
                            mVRuler->GetField(i).mSize);

            if(lPos.x>pRect.r||lPos.y>pRect.b||
                    lPos.x+lSize.x<pRect.l||lPos.y+lSize.y<pRect.t)
                continue;
            DrawCell(pGC,i,j,lPos,lSize);
        }
    }
}

void CTableBox::DrawCell(img::CGC *pGC,TID pRow,TID pCol,const CPoint_d &pPos,const CSize_d &pSize)
{
    bool lSel=mSelected.mValid&&mSelected.mRow==pRow&&mSelected.mCol==pCol;
    
    pGC->SetStockFont(L"small");
    pGC->SetSource(gConfig.mColors.Get(L"property_lines"));
    pGC->Path().MoveTo(CPoint_d(pPos.x,pPos.y+pSize.y-1));
    pGC->Path().LineTo(CPoint_d(pPos.x+pSize.x-1,pPos.y+pSize.y-1));
    pGC->Path().MoveTo(CPoint_d(pPos.x+pSize.x-1,pPos.y));
    pGC->Path().LineTo(CPoint_d(pPos.x+pSize.x-1,pPos.y+pSize.y-1));
    pGC->StrokePath();

    if(lSel)
    {
        pGC->SetSource(gConfig.mColors.Get(L"selection_back"));
        pGC->Path().Rect(pPos,pSize-1);
        pGC->FillPath();
    }

    pGC->SetSource(gConfig.mColors.Get(lSel?L"selection_text":L"edit_text"));

    mField->mType->Draw(mValues(pRow,pCol),pGC,
                                    CRect_d(pPos,pSize-1));
}

CTableBox::Position CTableBox::GetCellAt(const CPoint_d &pPoint)
{
    Position lReturn;
    
    lReturn.mValid=true;
    
    lReturn.mCol=mHRuler->GetIDAt(pPoint.x);
    lReturn.mRow=mVRuler->GetIDAt(pPoint.y);
    
    if(lReturn.mRow<0)
        lReturn.mValid=false;
    else if(lReturn.mRow>=mValues.size1())
        lReturn.mValid=false;
    else if(lReturn.mCol<0)
        lReturn.mValid=false;
    else if(lReturn.mCol>=mValues.size2())
        lReturn.mValid=false;
        
    return lReturn;
}

void CTableBox::StartEditing(TID pRow,TID pCol)
{
    CPoint_d lPos(mHRuler->GetField(pCol).mPos,
                        mVRuler->GetField(pRow).mPos);
    lPos-=mScrollPos;
    CSize_d lSize(mHRuler->GetField(pCol).mSize,
                    mVRuler->GetField(pRow).mSize);

    mEditing.mValid=true;
    mEditing.mRow=pRow;
    mEditing.mCol=pCol;
    mEditor=mField->mType->GetEditor();
    mEditor->sEndEdit.Connect(&CTableBox::EndEditing,this);
    mEditor->Start(mValues(pRow,pCol),this,CRect_d(lPos,lSize-1),img::CColor(1.0,1.0,1.0));
}

void CTableBox::EndEditing()
{
    if(!mEditing.mValid) return;
    mEditor->Finish(mValues(mEditing.mRow,mEditing.mCol));
    delete mEditor;
    eChanged(mEditing.mRow,mEditing.mCol,mValues(mEditing.mRow,mEditing.mCol));
    mEditing.mValid=false;
    Refresh();
}

void CTableBox::RestartEditing()
{
    if(!mEditing.mValid) return;
    Position lEditing=mEditing;
    EndEditing();
    StartEditing(lEditing.mRow,lEditing.mCol);
}

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/////////////////////// Event handlers ////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

void CTableBox::OnCreate()
{
    get_default_theme()->SetBackground(this);

    SetPointer(CPointer::STOCK_DEFAULT);

    mHScroll=new CScrollBar();
    mHScroll->eChanged.Connect(&CTableBox::OnHScroll,this,_1);
    mHScroll->CreateAndSet(this,CPoint_d(nUndefined),CSize_d(16,16),1,15,
                                                    CScrollBar::STYLE_HORIZONTAL);
    
    mHScroll->SetRange(0,15);
    mHScroll->SetStep(2,10);
    mHScroll->SetValue(0,false);

    mVScroll=new CScrollBar();
    mVScroll->eChanged.Connect(&CTableBox::OnVScroll,this,_1);
    mVScroll->CreateAndSet(this,CPoint_d(nUndefined),CSize_d(16,16),1,15);
    mVScroll->SetRange(0,15);
    mVScroll->SetStep(2,10);
    mVScroll->SetValue(0,false);

    attach_scroll_bars(mHScroll,mVScroll);

    mHRuler=new CRulerBox;
    mHRuler->Create(this,CSize_d(70,16));
    mHRuler->eMoved.Connect(&CTableBox::OnRulerChange,this,false,false,_2);
    mHRuler->eFirstMoved.Connect(&CTableBox::OnRulerChange,this,true,false,_1);
    mVRuler=new CRulerBox;
    mVRuler->Create(this,CSize_d(70,16));
    mVRuler->SetStyle(RBS_VERTICAL);
    mVRuler->eMoved.Connect(&CTableBox::OnRulerChange,this,false,true,_2);
    mVRuler->eFirstMoved.Connect(&CTableBox::OnRulerChange,this,true,true,_1);

    attach_ruler_bars(mHRuler,mVRuler);

    mHScroll->Show();
    mVScroll->Show();
    mHRuler->Show();
    mVRuler->Show();

    UpdateScrollBars();
}
    
void CTableBox::OnExpose(const CExposeEvent &pE)
{
    img::CGC *lGC=pE->mGC;
    DrawAll(lGC,pE->mRect);
}    

void CTableBox::OnHScroll(int pPos)
{
    int lScrollBy=(int)mScrollPos.x-pPos;
    mScrollPos.x=pPos;
    if(lScrollBy)
        ScrollBy(CPoint_d(lScrollBy,0));
    mHRuler->SetScroll(mScrollPos.x);
    RestartEditing();
}

void CTableBox::OnVScroll(int pPos)
{
    int lScrollBy=(int)mScrollPos.y-pPos;
    mScrollPos.y=pPos;
    if(lScrollBy)
        ScrollBy(CPoint_d(0,lScrollBy));
    mVRuler->SetScroll(mScrollPos.y);
    RestartEditing();
}

void CTableBox::OnButtonDown(CMouseEvent *pE)
{
    if(mEditing.mValid)
    {
        EndEditing();
    }

    if(pE->mButton==EMouseButton::LEFT)
    {
        Position lPos=GetCellAt(pE->mPoint);

        if(lPos.mValid)
        {
            if(!mSelected.mValid||mSelected.mRow!=lPos.mRow||
                                mSelected.mCol!=lPos.mCol)
            {
                sSelected(lPos.mRow,lPos.mCol);
                mSelected=lPos;
                EnsureVisible(mSelected.mRow,mSelected.mCol,false);
                Refresh();
            }
            if((!mEditing.mValid||mEditing.mRow!=lPos.mRow||
                        mEditing.mCol!=lPos.mCol)&&
                        !(mField->mStyle&CPropertyField::PLF_READONLY))
            {
                StartEditing(lPos.mRow,lPos.mCol);
            }
        }
        else if(mSelected.mValid)
        {
            sSelected(-1,-1);
            mSelected.mValid=false;
            Refresh();
        }
    }
    else if(pE->mButton==MOUSE_ZUP)
    {
        mVScroll->ScrollUp(gConfig.mMouse.GetWheelScroll());
    }
    else if(pE->mButton==MOUSE_ZDOWN)
    {
        mVScroll->ScrollDown(gConfig.mMouse.GetWheelScroll());
    }
}

void CTableBox::OnButtonUp(CMouseEvent*)
{
/*  if(pE->mButton==EMouseButton::LEFT)
    {
        if(mDragging)
        {
            mDragging=false;
        }
        else if(mSelecting)
        {
            if(mLastDragPoint!=mDragPoint)
            {
//              mGC->SetFunction(GCF_INVERT);
//              mGC->DrawArea(mDragPoint.x,mDragPoint.y,mLastDragPoint.x,mLastDragPoint.y);
//              mGC->SetFunction();

                RefreshRect(CRect_d(mDragPoint,mLastDragPoint));
            }
    
            mSelecting=false;
        }
    }
*/
}

//void CTableBox::OnDoubleClick(CMouseEvent *pE)
//{
/*  if(pE->mButton==EMouseButton::LEFT)
    {
        mDragging=false;
        mSelecting=false;
        Field *lItem=GetItemAt(pE->mPoint);     

        if(lItem)
        {
            OnItemDblClk(lItem);
        }
    }
*/
//}

void CTableBox::OnMouseMove(CMouseEvent*)
{
}

void CTableBox::OnKeyDown(const CKeyEvent &pE)
{
    if(pE->mKey==KEY_LEFT)
    {
        if(!mSelected.mValid) return;
        if(mSelected.mCol<=0) return;
        mSelected.mCol--;
        sSelected(mSelected.mRow,mSelected.mCol);
        EnsureVisible(mSelected.mRow,mSelected.mCol,true);
        Refresh();
    }
    else if(pE->mKey==KEY_RIGHT)
    {
        if(!mSelected.mValid) return;
        if(mSelected.mCol>=mValues.size2()-1) return;
        mSelected.mCol++;
        sSelected(mSelected.mRow,mSelected.mCol);
        EnsureVisible(mSelected.mRow,mSelected.mCol,true);
        Refresh();
    }
    else if(pE->mKey==KEY_UP)
    {
        if(!mSelected.mValid) return;
        if(mSelected.mRow<=0) return;
        mSelected.mRow--;
        sSelected(mSelected.mRow,mSelected.mCol);
        EnsureVisible(mSelected.mRow,mSelected.mCol,true);
        Refresh();
    }
    else if(pE->mKey==KEY_DOWN)
    {
        if(!mSelected.mValid) return;
        if(mSelected.mRow>=mValues.size1()-1) return;
        mSelected.mRow++;
        sSelected(mSelected.mRow,mSelected.mCol);
        EnsureVisible(mSelected.mRow,mSelected.mCol,true);
        Refresh();
    }
}

void CTableBox::OnSize(const CGeometryEvent &pE)
{
    UpdateScrollBars();
    if(mEditing.mValid)
    {
        RestartEditing();
    }
}

void CTableBox::OnStyleChanged(TStyle)
{
//  Refresh();
}

void CTableBox::OnRulerChange(bool pFirst,bool /*pVertical*/,double /*pSize*/)
{
    if(!pFirst)
    {
        EndEditing();
        Refresh();
        UpdateScrollBars();
    }
}

/*namespace gui*/ } /*namespace buola*/ }
#endif